home *** CD-ROM | disk | FTP | other *** search
/ FishMarket 1.0 / FishMarket v1.0.iso / fishies / 526-550 / disk_542 / chemnimate / cmtsource.lzh / ch14.c < prev    next >
C/C++ Source or Header  |  1991-08-28  |  10KB  |  343 lines

  1. /****************************************************************
  2.  *                                *
  3.  *    ChemNiMate    to Animate Chemical Reactions        *
  4.  *                                *
  5.  *                                *
  6.  *    this program is written to show how molecules        *
  7.  *        are in 3-d    and how mechanisms work.    *
  8.  *                                *
  9.  *                                *
  10.  *                                *
  11.  *Note that this program is entirely written using integers!!!    *
  12.  *                                *
  13.  *==============================================================*
  14.  *Vers. Date    Author    Comment                 *
  15.  *sk1    22Mar91 KvGend    started working on it.            *********
  16.  *sk5    24Mar91 KvGend    is now able to rotate some complicated formula  *
  17.  *sk9    30Mar91 KvGend    Now accepts scripts. Is able to play        *
  18.  *            along with penicilline                *
  19.  *ch3    02Apr91 KvGend    Rewrote parser and put it in separate file.    *
  20.  *ch6    07Apr91 KvGend    Corrected bugs, now is parser able to use    *
  21.  *            full words as commands.                *
  22.  *ch9   27Apr91 KvGend  Corrected bugs, now parser skips spaces        *
  23.  *            at the beginning/no more GURU when a ball flies    *
  24.  *            out of the screen. A lot of objects added.    *
  25.  *ch11    13Jun91    KvGend    now loads full script in memory before executing*
  26.  *            it.                        *
  27.  *ch12    17Jul91    KvGend    Added second displaymode, added skip, improved    *
  28.  *            the Loop/Until.                    *
  29.  *ch14    28Aug91    KvGend    First release (I HOPE)                *
  30.  *                                    *
  31.  *                                    *
  32.  *                                    *
  33.  *                                    *
  34.  ************************************************************************/
  35.  
  36.  
  37. #ifdef AMIGA            /* some amiga-specific stuff */
  38. #include <exec/types.h>
  39. #include <graphics/rastport.h>
  40. extern struct GfxBase *gfxbase;
  41. struct RastPort rastport;
  42. extern struct BitMap *bitmap, *sourcebitmap;
  43. #endif
  44.  
  45. #include "std:gonio.c"        /* the provision of cos() and sin()*/
  46. #include "uni4.h"
  47. #include "/k/k5.h"        /* to provide the linked lists */
  48.  
  49. char header[] = " ChemNiMate, to animate Chemical Structs  ";
  50. char footer[] = "            © 1991 KP van Gend/R Knaapen  ";
  51.  
  52. struct DisplayInfo di =        /* default-values */
  53. {
  54.   180, 125,            /*middle-(x,y) */
  55.   65536, 1,            /* angle,delta-angle */
  56.   0 | LINES | BALLS,        /* displaymodes */
  57.   1,                /* which playfield is active */
  58. };
  59.  
  60. int volg[MXNUMB];
  61. int array[MXNUMB][8];
  62.  
  63. FILE *infile;
  64.  
  65. extern char *tlist[];        /* the list with tokens */
  66. extern struct ParserInfo pi;
  67.  
  68. /***********************prototypes**********/
  69. /* in parser##.c */
  70. extern int parser (char *, int);
  71. /* in 2nd##.c */
  72. extern SetUp (void);
  73. extern SwapShow ();
  74. extern Quit (void);
  75.  
  76. /*********************************main()***/
  77. main (int argc, char **argv)
  78. {
  79.   char regel[255];        /* the linebuffer (regel{Dutch}=line{Eng})*/
  80.   char *line;
  81.   int i, dummy, listnr;
  82.   HEAD_T *hoofd;
  83.   INFO_T *vel;
  84.  
  85.   if (argc != 2)
  86.     {
  87.       printf ("ChemNiMate was written to animate Chemistry Structures\n© by KP van Gend & R Knaapen\nUSAGE: %s <NameOfScript>\n", argv[0]);
  88.       exit (0);
  89.     }
  90.   infile = (FILE *) fopen (argv[1], "r");
  91.   if (infile == NULL)
  92.     {
  93.       printf ("file does not exist\n");
  94.       exit (5);
  95.     }
  96. /*****inlezen file *****/
  97.   hoofd = create ();
  98.   pi.linenr = 0;
  99.  
  100.   printf ("PASS 1: (loading)\n");
  101.   while (fgets (regel, 254, infile) != NULL)
  102.     {
  103.       pi.linenr++;
  104.       line = regel;
  105.  
  106. /* remove preceding spaces/TABs */
  107.       for (; line[0] == ' ' || line[0] == 9;)
  108.     line++;
  109. /* remove a remark */
  110.       for (i = 0; i < strlen (line); i++)
  111.     if (line[i] == ';')
  112.       {
  113.         line[i] = 10;    /* replace it by a hard-return*/
  114.         line[i + 1] = 0;    /* and end it up here */
  115.       }
  116. /* correct a binary minus: [7 - 3] should be [7 _ 3] */
  117.       for (i = 0; (i < strlen (line)) && (line[i] != '\"'); i++)
  118.     if (line[i] == '-' && !ISNUM (line[i + 1]))
  119.       line[i] = '_';
  120. /* make uppercase of all applicable stuff */
  121.       for (i = 0; i < strlen (line); i++)
  122.     {
  123.       line[i] = toupper (line[i]);
  124.       if (line[i] == '\"')
  125.         break;
  126.     }
  127. /* find token in list*/
  128.       listnr = 0;
  129.       if (line[0] == ';' || line[0] == 10)
  130.     listnr = -1;
  131.       else
  132.     while (tlist[listnr][0])
  133.       {
  134.         dummy = tlist[listnr][0] & 0xff;
  135.         for (i = 0; tlist[listnr][i + 2] != 0; i++)    /* compare two strings*/
  136.           if (tlist[listnr][i + 2] != line[i])
  137.         dummy = 0;
  138.         if (dummy != 0)    /*strings are the same*/
  139.           break;
  140.         listnr++;
  141.       }
  142. /* and save it to the linked list */
  143.       append (makeinfo (pi.linenr, listnr, line), hoofd);
  144.     }                /* end-of-while(fgets( )) */
  145.  
  146.   fclose (infile);        /* close file*/
  147.  
  148. /*****start executing ******/
  149.   SetUp ();
  150.   printf ("PASS 2: (executing)\n");
  151.  
  152.   pi.linenr = 1;
  153.   while (vel = gimmelinnr (hoofd, pi.linenr))
  154.     {
  155.       pi.linenr++;
  156.       if (vel->token == -1)    /* this is an empty line*/
  157.     continue;
  158.       /* copy line to buffer*/
  159.       for (i = 0; i < strlen (vel->string); i++)
  160.     regel[i] = vel->string[i];
  161.       regel[i] = '\0';
  162.       parser (regel, vel->token);
  163.     }
  164.  
  165. /*****We're finished now...******/
  166.   Quit ();
  167.   return(0);    /*nothing wrong...*/
  168. }                /*****end-of-main()*/
  169.  
  170.  
  171. /**************************TextAt()************************/
  172. TextAt (int xc, int yc, char *string)
  173. {
  174.   MOVE (xc + LBOR, yc + UBOR);
  175.   TEXT (string);
  176. }
  177.  
  178. /**************************LetItShow()*********************/
  179. LetItShow (int nrframes, int start, int maxnr)
  180. {
  181.   int teller;
  182.  
  183. /* init sort-array (name: volg) */
  184.   for (teller = start; teller <= maxnr; teller++)
  185.     volg[teller] = teller;
  186.   
  187.   if (nrframes==0)
  188.     teller=0;
  189.   else
  190.     teller=1;
  191.  
  192.   for (; teller <= nrframes; teller++)
  193.     {
  194.       di.angle += di.dangle;    /* rotate figure, if necessary*/
  195.  
  196.       if (di.modes % 16 == 0)
  197.     DrawBalls0 (start, maxnr);    /* draw balls 3-d */
  198.       if (di.modes % 16 == 1)
  199.     DrawBalls1 (start, maxnr);    /* draw balls 2-d (watch along y-axis)*/
  200.       COLOR (1);        /*print header */
  201.       TextAt (2, 7, header);
  202.       TextAt (2, VHEIGHT - 3, footer);    /*print footer */
  203.       if (nrframes!=0)
  204.     SwapShow();
  205.     }
  206. }
  207.  
  208. /*******************************DrawBalls0(startnr,maxnr)****/
  209. DrawBalls0 (int start, int maxnr)
  210. {
  211.   int j, quit;
  212.   int scrx, scry;
  213.  
  214.   COLOR (1);            /* I just put it here */
  215. /***** uitrekenen van de Carthesische coördinaten */
  216.   for (j = start; j <= maxnr; j++)
  217.     {
  218.       array[j] XC = Sin (di.angle + array[j] ADD, array[j] RAD);
  219.       array[j] YC = Cos (di.angle + array[j] ADD, array[j] RAD);
  220.       array[j] ZC = array[j] HEIGHT;
  221.     }
  222. /***** (her)sorteren van de atomen op diepte (x-as) */
  223.   do
  224.     {
  225.       quit = 245;        /* just a random value */
  226.       for (j = start; j < maxnr; j++)
  227.     if (array[volg[j]] XC < array[volg[j + 1]] XC)
  228.       {
  229.         quit = volg[j];
  230.         volg[j] = volg[j + 1];
  231.         volg[j + 1] = quit;
  232.       }
  233.   } while (quit != 245);
  234. /***** van achter naar voren toe alle balletjes plaatsen */
  235.   for (quit = maxnr; quit >= start; quit--)
  236.     {
  237.       j = volg[quit];
  238.       scrx = RX (array[j] YC, array[j] XC);
  239.       scry = RY (ARR ZC, ARR XC);
  240.       if (ARR BIND == j)
  241.     PutBall (scrx, scry, array[j] KIND);
  242.       else if (ARR XC > array[ARR BIND] XC)    /* draw line or ball first */
  243.     {
  244.       PleaseLine (scrx, scry, ARR BIND);
  245.       PutBall (scrx, scry, array[j] KIND);
  246.     }
  247.       else
  248.     {
  249.       PutBall (scrx, scry, array[j] KIND);
  250.       PleaseLine (scrx, scry, ARR BIND);
  251.     }
  252.     }                /*end-of-for*/
  253. }                /****end-of-DrawBalls0***/
  254.  
  255. /*******************************DrawBalls1(startnr,maxnr)****/
  256. DrawBalls1 (int start, int maxnr)
  257. {
  258.   int j, quit;
  259.  
  260.   COLOR (1);            /* I just put it here */
  261. /***** calculate Carthesian coordinates */
  262.   for (j = start; j <= maxnr; j++)
  263.     {
  264.       array[j] XC = di.mx + Cos (di.angle + array[j] ADD, array[j] RAD);
  265.       array[j] YC = di.my - Sin (di.angle + array[j] ADD, array[j] RAD);
  266.       array[j] ZC = array[j] HEIGHT;
  267.     }
  268. /***** (re)sort van de atomen depth (x-y plane ) */
  269.   do
  270.     {
  271.       quit = 245;        /* just a random value */
  272.       for (j = start; j < maxnr; j++)
  273.     if (array[volg[j]] ZC < array[volg[j + 1]] ZC)
  274.       {
  275.         quit = volg[j];
  276.         volg[j] = volg[j + 1];
  277.         volg[j + 1] = quit;
  278.       }
  279.   } while (quit != 245);
  280. /***** put all balls, from below to up */
  281.   for (quit = maxnr; quit >= start; quit--)
  282.     {
  283.       j = volg[quit];
  284.       if (ARR BIND == j)
  285.     PutBall (array[j] XC, array[j] YC, array[j] KIND);
  286.       else if (ARR ZC < array[ARR BIND] ZC)    /* draw line or ball first */
  287.     {
  288.       PleaseLine1 (ARR XC, ARR YC, ARR BIND);
  289.       PutBall (ARR XC, ARR YC, ARR KIND);
  290.     }
  291.       else
  292.     {
  293.       PutBall (ARR XC, ARR YC, ARR KIND);
  294.       PleaseLine1 (ARR XC, ARR YC, ARR BIND);
  295.     }
  296.     }                /*end-of-for*/
  297. }                /****end-of-DrawBalls1()****/
  298.  
  299. /***********************************PutBall( scrx, scry,which ball)******/
  300. PutBall (int scrx, int scry, int k)
  301. {
  302.   if (di.modes & BALLS)        /* don't draw a ball when bit is set */
  303.     if (scrx < LBOR | scrx > LBOR + VWIDTH | scry < UBOR | scry > UBOR + VHEIGHT)
  304.       pi.error = OUTSCREEN_ERR;
  305.     else
  306.       {
  307. /* now follows the routine to put a ball with its centre at (scrx,scry)
  308.  * first the Background at that place is erased, then the ball
  309.  * is OR'ed in the bitmap.
  310.  */
  311. #ifdef AMIGA
  312.     BltBitMap (SBM, 32 + (k & 7) * 32, 4 * (k & (~7)), BM, scrx, scry, 31, 31, 0x20, 0xF, 0);
  313.     BltBitMap (SBM, (k & 7) * 32, 4 * (k & (~7)), BM, scrx, scry, 31, 31, 0xE0, 0xF, 0);
  314. #endif
  315.       }
  316. }
  317.  
  318. /*********************************PleaseLine(scrx,srcy,to whichball)******/
  319. PleaseLine (int scrx, int scry, int nr)
  320. {
  321.   if (di.modes & LINES)
  322.     if (scrx < LBOR | scrx > LBOR + VWIDTH | scry < UBOR | scry > UBOR + VHEIGHT)
  323.       pi.error = OUTSCREEN_ERR;
  324.     else
  325.       {
  326.     MOVE (scrx + 16, scry + 16);
  327.     LINETO (RX (array[nr] YC, array[nr] XC) + 16,
  328.         RY (array[nr] ZC, array[nr] XC) + 16);
  329.       }
  330. }
  331.  
  332. PleaseLine1 (int scrx, int scry, int nr)
  333. {
  334.   if (di.modes & LINES)
  335.     if (scrx < LBOR | scrx > LBOR + VWIDTH | scry < UBOR | scry > UBOR + VHEIGHT)
  336.       pi.error = OUTSCREEN_ERR;
  337.     else
  338.       {
  339.     MOVE (scrx + 16, scry + 16);
  340.     LINETO (array[nr] XC + 16, array[nr] YC + 16);
  341.       }
  342. }
  343.